package com.moodincode.taskcenter.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringContextUtil.applicationContext == null) {
            SpringContextUtil.applicationContext = applicationContext;
        }
        log.info("init ApplicationContext and  BeanFactory Success.");
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 根据bean名称获取bean对象
     * @param beanName
     * @return
     */
    public static Object getBean(String beanName) {
        try {
            return applicationContext.getBean(beanName);
        }catch (Exception e){}
        return null;
    }

    /**
     * 根据bean的实例化类获取bean对象
     * @param cls
     * @return
     */
    public static Object getBean(Class cls) {
        try {
            return applicationContext.getBean(cls);
        }catch (Exception e){}
        return null;
    }

    /**
     * 注册bean对象
     * @param name
     * @param clazz
     * @param <T>
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public static  <T> T registerBean(String name, Class<T> clazz) throws InstantiationException, IllegalAccessException {

        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
        ConfigurableListableBeanFactory beanFactory = configurableApplicationContext.getBeanFactory();
        //注册普通对象为bean对象
        beanFactory.registerSingleton(name, clazz.newInstance());
        //获取bean对象
        T contextBean = applicationContext.getBean(name, clazz);
        //自动注入@value等属性值的依赖
        beanFactory.autowireBeanProperties(contextBean, AutowireCapableBeanFactory.AUTOWIRE_NO,true);
        //自动注入bean依赖
        beanFactory.autowireBean(contextBean);
        return contextBean;
    }
}
